package com.phaeton.beemeup.entity;

import java.util.UUID;
import java.util.Map.Entry;

import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.engine.handler.timer.ITimerCallback;
import org.andengine.engine.handler.timer.TimerHandler;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import com.phaeton.beemeup.GameManager;

import android.util.Log;

public abstract class Comb  extends AnimatedSprite implements IComb{
	private int resource = 0;
	protected int state = 0;
	protected int col;
	protected int row;
	private Insect occupant;
	private TimerHandler dumpingHandler;
	protected GameManager mGameManager;
	protected int structure = 3;
	
	public Comb(int col, int row, ITiledTextureRegion pTiledTextureRegion, final GameManager pGameManager) {
		super(pGameManager.getLevel().getCell(col, row).getX(), pGameManager.getLevel().getCell(col, row).getY(), pTiledTextureRegion, pGameManager.getActivity().getVertexBufferObjectManager());
		mGameManager = pGameManager;
		this.col = col;
		this.row = row;
		
		dumpingHandler = new TimerHandler(1, true, new ITimerCallback(){

			@Override
			public void onTimePassed(TimerHandler pTimerHandler) {
				if(resource < 5 && occupant != null && occupant.getResource() > 0 ){
					resource++;
					occupant.changeResource(-1);
				}else{
					Comb.this.unregisterUpdateHandler(pTimerHandler);
					occupant.removeState(IInsect.DUMPING);
				}
			}
        	
        });
		
		this.registerUpdateHandler(new IUpdateHandler() {
			public void onUpdate(float pSecondsElapsed) {
				
				switch(resource){
					case 0: stopAnimation(0);break;
					case 1: stopAnimation(1);break;
					case 2: stopAnimation(2);break;
					case 3: stopAnimation(3);break;
					case 4: stopAnimation(4);break;
					case 5: stopAnimation(5);break;
					default: stopAnimation(0);break;
				}
			}

			public void reset() {
			}
          });
	}

	public void occupy(final Insect occupant){
		this.occupant = occupant;
		this.addState(Comb.OCCUPIED);
		//Log.e("OccupyComb", "Comb "+this.toString()+" occupied by "+occupant.toString());
		
		if((occupant.getState() & Insect.INJURED) != 0){
			occupant.addState(Insect.REGENERATION);
			this.registerUpdateHandler(new TimerHandler(5, false, new ITimerCallback(){

				@Override
				public void onTimePassed(TimerHandler pTimerHandler) {
					if(occupant != null){ 
						Comb.this.unregisterUpdateHandler(pTimerHandler);
						occupant.heal();
						pTimerHandler.reset();
					}
				}
	        }));
		}
		
		if(occupant.getResource() > 0 && resource < 5){
			occupant.addState(Insect.DUMPING);
			this.registerUpdateHandler(dumpingHandler);
		}
		
		if(occupant instanceof Wasp && this instanceof BeeComb) {
			UUID beeCombID = null;
			for(UUID lBeeCombID: mGameManager.getBeeCombs().keySet()){
				//Log.e("Insect", "BeeComb: " + lBeeCombID);
				if(mGameManager.getBeeCombs().get(lBeeCombID).equals(this)){
					beeCombID = lBeeCombID;
					break;
				}
			}
			this.damageComb(beeCombID, occupant);
		}
		
		if(occupant instanceof Bee && this instanceof WaspComb) {
			UUID waspCombID = null;
			for(UUID lWaspCombID: mGameManager.getWaspCombs().keySet()){
				//Log.e("Insect", "BeeComb: " + lBeeCombID);
				if(mGameManager.getWaspCombs().get(lWaspCombID).equals(this)){
					waspCombID = lWaspCombID;
					break;
				}
			}
			this.damageComb(waspCombID, occupant);
		}
	}
	
	public void deOccupy(){
		if(occupant != null) occupant.removeState(IInsect.DUMPING);
		occupant = null;
		this.removeState(Comb.OCCUPIED);
		//Log.e("OccupyComb", "Comb "+this+" deoccupied by "+occupant);
		
		this.unregisterUpdateHandler(dumpingHandler);
	}

	public Insect getOccupant() {
		return occupant;
	}

	public void setOccupant(Insect occupant) {
		this.occupant = occupant;
	}
	
	/*Getter*/
	public int getCol() {
		return col;
	}
	
	public int getRow() {
		return row;
	}
	
	public int getState() {
		return state;
	}
	
	public int getResource() {
		return resource;
	}
	
	public int getStructure() {
		return structure;
	}
	
	/*Setter*/
	public void changeResource(int i) {
		this.resource += i;
	}

	public void setResource(int resource) {
		this.resource = resource;
	}
	
	public void addState(int state) {
		this.state |= state;
	}
	
	public void removeState(int state) {
		this.state &= ~state;
	}
	
	public void changeStructure(int i){
		structure += i;
	}

	public void setStructure(int structure) {
		this.structure = structure;
		
	}
	
	abstract public void damageComb(final UUID combID, final Insect attacker);
}
